/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hxg.portmgr.core.oper.snmp.expand;

import hxg.portmgr.core.device.DeviceType;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import hxg.portmgr.core.oper.snmp.SnmpOper;

/**
 *
 * @author hxg
 */
public class SnmpOperTable {

    //final static File f = new File("SnmpOperPlugin.xml");
    final static EnumMap<DeviceType, List<Class<? extends SnmpOper>>> SnmpOperPluginMap = new EnumMap(DeviceType.class);

    final static File savefile = new File(".\\conf\\SnmpOperPlugins.xml");

    static {
        try {
            load();
            if (!savefile.exists()) {
                savefile.getParentFile().mkdirs();
            }
            System.out.println(SnmpOperPluginMap);
            JaxbEncode(savefile);
        } catch (IOException ex) {
            Logger.getLogger(SnmpOperTable.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void load() throws IOException{
        SnmpOperPluginMap.clear();
        SnmpOperPluginMap.putAll(JaxbDecode(savefile));
        
    }

    public static List<Class<? extends SnmpOper>> getClassListOfType(DeviceType type) {
        if (SnmpOperPluginMap.containsKey(type)) {
            return SnmpOperPluginMap.get(type);
        } else {
            return new ArrayList();
        }
    }

    public static void JaxbEncode(File f) {
        PrintWriter pw=null;
        try {
            pw = new PrintWriter(f);
            JAXBContext jc = JAXBContext.newInstance(SnmpOperClassListBean.class);
            Marshaller m = jc.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            SnmpOperClassListBean listBean = new SnmpOperClassListBean();
            for (DeviceType type : SnmpOperPluginMap.keySet()) {
                List<Class<? extends SnmpOper>> plugins = SnmpOperPluginMap.get(type);
                DeviceTypeToSnmpOperPluginsEntry entry = new DeviceTypeToSnmpOperPluginsEntry();
                entry.type = type;
                for (Class<? extends SnmpOper> c : plugins) {
                    entry.snmpOperplugin.add(c.getName());
                }
                listBean.entries.add(entry);
            }
            m.marshal(listBean, pw);
            pw.flush();
        } catch (Exception ex) {
            Logger.getLogger(SnmpOperTable.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            pw.close();
        }
    }

    public static EnumMap<DeviceType, List<Class<? extends SnmpOper>>> JaxbDecode(File f) {
        try {
            EnumMap<DeviceType, List<Class<? extends SnmpOper>>> mp = new EnumMap(DeviceType.class);
            JAXBContext jc = JAXBContext.newInstance(SnmpOperClassListBean.class);
            Unmarshaller u = jc.createUnmarshaller();
            SnmpOperClassListBean listbean = (SnmpOperClassListBean) u.unmarshal(f);
            for (DeviceTypeToSnmpOperPluginsEntry entry : listbean.entries) {
                DeviceType type = entry.type;
                List<Class<? extends SnmpOper>> classlist = new ArrayList();
                for (String plugin : entry.snmpOperplugin) {
                    try {
                        classlist.add((Class<? extends SnmpOper>) Class.forName(plugin));
                    } catch (ClassNotFoundException ex) {
                        Logger.getLogger(SnmpOperTable.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                mp.put(type, classlist);
            }
            return mp;
            //return dlist.list;
        } catch (JAXBException ex) {
            Logger.getLogger(SnmpOperTable.class.getName()).log(Level.SEVERE, null, ex);
            return new EnumMap(DeviceType.class);
        }
    }
}
